package com.intellij.licensecommon.util;

import org.jetbrains.rsa.RSADecoder;

import java.math.BigInteger;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class SubscriptionLicenseDecoder {
    private static BigInteger PUBLIC_MOD = new BigInteger("bb62fbb57f105cd61b47ae2290fcb3ce1179942de171beddf6baa1a521b9368b735c7c931902eba8de6d160711a6ecc40f4a5e766e9fcdee8a38715db572ad3d", 16);
    private static BigInteger PUBLIC_EXP = new BigInteger("10001", 16);

    private static final Pattern LICENSE_PATTERN = Pattern.compile("=+\\s+LICENSE (BEGIN|END)\\s+=+");

    public static SubscriptionLicenseInfo decodeLicenseKey(String licenseKey, String username) throws a {
        SubscriptionLicenseInfo info = new SubscriptionLicenseInfo();

        byte[] arrayOfByte = a(licenseKey, info);

        a(arrayOfByte, info, username, 14);
        b(arrayOfByte, info, username, -1);
        return info;
    }

    protected static byte[] a(String licenseKey, SubscriptionLicenseInfo info) throws a {
        return decode(licenseKey, info, PUBLIC_EXP, PUBLIC_MOD);
    }

    protected static byte[] decode(String licenseKey, SubscriptionLicenseInfo info, BigInteger publicExponent, BigInteger publicModulus) throws a {
        Matcher localMatcher = LICENSE_PATTERN.matcher(licenseKey);
        licenseKey = localMatcher.replaceAll("").trim();

        int i = licenseKey.indexOf('\n');
        if (i < 0) {
            i = licenseKey.indexOf('\r');
        }
        if (i < 0) {
            throw new a();
        }
        String str = licenseKey.substring(0, i);
        int j = str.indexOf('-');
        if (j > 0) {
            try {
                info.customerId = Integer.parseInt(str.substring(0, j));
            } catch (NumberFormatException localNumberFormatException) {
                throw new a();
            }
        } else {
            info.customerId = -1;
        }
        return new RSADecoder(publicExponent, publicModulus, 64).decode(licenseKey.substring(i + 1));
    }

    static void a(byte[] licenseBytes, SubscriptionLicenseInfo info, String paramString, int paramInt) throws a {
        if (licenseBytes.length != paramInt) {
            byte[] arrayOfByte;
            if (licenseBytes.length == paramInt + 1) {
                if (licenseBytes[0] == 0) {
                    arrayOfByte = new byte[paramInt];
                    System.arraycopy(licenseBytes, 1, arrayOfByte, 0, paramInt);
                    licenseBytes = arrayOfByte;
                } else {
                    throw new a();
                }
            } else if (licenseBytes.length < paramInt) {
                arrayOfByte = new byte[paramInt];
                System.arraycopy(licenseBytes, 0, arrayOfByte, paramInt - licenseBytes.length, licenseBytes.length);
                licenseBytes = arrayOfByte;
            } else {
                throw new a();
            }
        }
        if (paramString != null) {
            int i = LicenseUtil.calcChecksum(paramString, info.customerId, licenseBytes);
            if (licenseBytes[(paramInt - 2)] != (byte) (i & 0xFF)) {
                throw new a();
            }
            if (licenseBytes[(paramInt - 1)] != (byte) (i >> 8 & 0xFF)) {
                throw new a();
            }
        }
    }

    static void b(byte[] licenseBytes, SubscriptionLicenseInfo info, String paramString, int paramInt) throws a {
        try {
            info.b = paramString;
            info.productId = (licenseBytes[0] & 0xF);
            info.licenseId = (licenseBytes[0] >> 4);
            info.majorVersion = (licenseBytes[1] & 0xF);
            info.minorVersion = (licenseBytes[1] >> 4);

            long generationTime = (licenseBytes[2] & 0xFFL) + ((licenseBytes[3] & 0xFF) << 8) + ((licenseBytes[4] & 0xFF) << 16) + ((licenseBytes[5] & 0xFF) << 24) << 16;
            info.generationDate = new Date(generationTime);

            int days = (licenseBytes[6] & 0xFF) + ((licenseBytes[7] & 0xFF) << 8);

            if (days != 0) {
                info.expirationDate = new Date(generationTime + days * 24L * 60L * 60L * 1000L);
            }

            int j = paramInt > -1 ? paramInt : (licenseBytes[10] & 0xFF) + ((licenseBytes[11] & 0xFF) << 8);
            if (days != 0) {
                j = days;
            }
            info.maintenanceDueDate = new Date(generationTime + j * 24L * 60L * 60L * 1000L);
        } catch (ArrayIndexOutOfBoundsException aiobe) {
            throw new a();
        }
    }
}
